﻿#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "DynamicArray.h"

/*
//1.先定义所需的数据信息结构；
struct DynamicArr
{
	//2.数组存储元素的空间的首地址；
	void** addr;
	//3.存储数据的内存空间，最大可存储的元素的容量空间；也就是最大存储元素的个数；
	int capacity;
	//4.当前存储数据的内存空间，存储的元素个数；当前已经存储元素的个数；
	int size;
};*/

struct PersonArr
{
	char name[64];
	int age;
};

/*
//5.初始化数组；
struct DynmicArr* Init_DynamicArr(int capacity)
{
	if (capacity <= 0)
	{
		return NULL;
	}
	struct DynamicArr* arr = malloc(sizeof(struct DynamicArr));
	if (NULL == arr)
	{
		return NULL;
	}
	arr->capacity = capacity;
	arr->addr = malloc(sizeof(void*) * arr->capacity);
	arr->size = 0;

	return arr;
}
//6.插入元素；
void Insert_DynamicArr(struct DynamicArr* arr, int pos, void* data)
{
	if (NULL == arr)
	{
		return;
	}
	if (NULL == data)
	{
		return;
	}

	if (pos<0 || pos>arr->size)
	{
		pos = arr->size;
	}
	//8.判断空间是否足够；
	if (arr->size >= arr->capacity)
	{
		//9.数组元素个数超过数组的容量空间个数，就申请一块更大的内存空间；
		int newCapacity = arr->capacity * 2;
		void** newSpace = malloc(sizeof(void*) * newCapacity);

		//10.将原来空间的数据拷贝到新空间；
		memcpy(newSpace, arr->addr, sizeof(void*) * arr->capacity);

		//11.释放原来空间的内存；
		free(arr->addr);

		//12.更新addr的指向；
		arr->addr = newSpace;
		arr->capacity = newCapacity;
	}

	//13.移动元素，给pos位置空出位置来；
	for (int i = arr->size - 1; i >= pos; --i)
	{
		arr->addr[i + 1] = arr->addr[i];
	}
	//14.将新元素插入到pos位置；
	arr->addr[pos] = data;
	arr->size++;
}
//7.遍历；
void Foreach_DynamicArr(struct DynamicArr* arr, void(*_callback)(void*))
{
	if (NULL == arr)
	{
		return;
	}
	if (NULL == _callback)
	{
		return;
	}
	for (int i = 0; i < arr->size; ++i)
	{
		_callback(arr->addr[i]);
	}
}*/

void myPrint_callback(void* data)
{
	struct PersonArr* person = (struct PersonArr*)data;
	printf("18.使用回调函数myPrint_callback数组元素person的Name：%s  Age：%d\n", person->name, person->age);
}

/*
//21.按位置删除元素；
void RemoveByPos_DynamicArr(struct DynamicArr* dArr, int pos)
{
	if (NULL == dArr)
	{
		return;
	}
	if (pos<0 || pos>dArr->size - 1)
	{
		return;
	}
	for (int i = pos; i < dArr->size; ++i)
	{
		//22.就是将后一个元素赋值给pos位置，然后pos位置后的元素整体向前挪一位；
		dArr->addr[i] = dArr->addr[i + 1];
	}
	dArr->size--;
}
//23.按值删除元素；
void RemoveByValue_DynamicArr(struct DynamicArr* dArr, void* data, int(*compare)(void*, void*))
{
	if (NULL == dArr)
	{
		return;
	}
	if (NULL == data)
	{
		return;
	}
	if (NULL == compare)
	{
		return;
	}
	for (int i = 0; i < dArr->size; ++i)
	{
		//24.如果值data和dArr->addr[i]相等，就删除dArr->addr[i]；
		if (compare(dArr->addr[i], data))
		{
			RemoveByPos_DynamicArr(dArr, i);
			break;
		}
	}
}*/

int myCompare(void* d1, void* d2)
{
	struct PersonArr* p1 = (struct PersonArr*)d1;
	struct PersonArr* p2 = (struct PersonArr*)d2;

	//27.返回true或false；
	return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}

/*
//25.销毁动态数组dArr；
void Destroy_DynamicArr(struct DynamicArr* dArr)
{
	if (NULL == dArr)
	{
		return;
	}
	if (dArr->addr != NULL)
	{
		free(dArr->addr);
		dArr->addr = NULL;
	}
	free(dArr);
	dArr = NULL;
}*/

void testDynamicArray()
{
	//15.创建动态数组；
	struct DynamicArr* dArr = Init_DynamicArr(5);
	//16.动态数组添加元素；
	struct PersonArr p1 = { "aaa",10 };
	struct PersonArr p2 = { "bbb",20 };
	struct PersonArr p3 = { "ccc",30 };
	struct PersonArr p4 = { "ddd",40 };
	struct PersonArr p5 = { "eee",50 };
	struct PersonArr p6 = { "fff",60 };

	//17.在位置100处，插入结构体元素p1,p2,p3,p4,p5,p6；
	/*Insert_DynamicArr(dArr, 100, &p1);
	Insert_DynamicArr(dArr, 100, &p2);
	Insert_DynamicArr(dArr, 100, &p3);
	Insert_DynamicArr(dArr, 100, &p4);
	Insert_DynamicArr(dArr, 100, &p5);*/

	Insert_DynamicArr(dArr, 0, &p1);
	Insert_DynamicArr(dArr, 0, &p2);
	Insert_DynamicArr(dArr, 0, &p3);
	Insert_DynamicArr(dArr, 1, &p4);
	Insert_DynamicArr(dArr, 1, &p5);

	printf("19.此时动态数组dArr的容量capacity为：%d\n", dArr->capacity);//5
	Insert_DynamicArr(dArr, 100, &p6);
	printf("20.此时动态数组dArr的容量capacity为：%d\n", dArr->capacity);//10

	Foreach_DynamicArr(dArr, myPrint_callback);//aaa,10  ...  fff,60 --> 30,50,40,20,10,60
	printf("------------------------------26.开始删除指定元素：-----------------------------\n");
	RemoveByPos_DynamicArr(dArr, 2);
	Foreach_DynamicArr(dArr, myPrint_callback);//30,50,20,10,60

	printf("------------------------------28.继续删除指定元素：-----------------------------\n");
	struct PersonArr pDel = { "aaa",10 };
	RemoveByValue_DynamicArr(dArr, &pDel, myCompare);
	//dArr->size = 0;
	//dArr->addr = NULL;
	Foreach_DynamicArr(dArr, myPrint_callback);//30,50,20,60

	//29.销毁动态数组；
	Destroy_DynamicArr(dArr);
}

//main221：动态数组初始化插入遍历删除销毁
int main221()
{
	testDynamicArray();

	system("pause");
	return EXIT_SUCCESS;
}